var EventProxy = require('eventproxy');

var logger = require('../models/logger');
var resultJson = require('../result-json');
var arrayHelper = require('./arrayHelper');

var dbHelper = {
    list: function(table, opt, sort, start, count, res, cb) {
        var proxy = new EventProxy();
        proxy.all('results', 'count', function(results, count) {
            var result = {
                results: results,
                count: count,
            };
            if (cb) {
                cb(result);
            } else {
                return res.send(resultJson(0, result));
            }
        })

        table.find(opt).skip(start).limit(count).sort(sort).exec(function(err, items) {
            if (err) {
                logger.error(err);
                return res.send(resultJson(2));
            }
            proxy.emit('results', items);
        });

        table.find(opt).count(function(err, num) {
            if (err) {
                logger.error(err);
                return res.send(resultJson(2));
            }
            proxy.emit('count', num);
        });
    },

    upsert: function(table, item, res, cb) {
        if (item._id) {
            var _id = item._id;
            delete item._id;
            table.update({
                _id: _id
            }, {
                $set: item
            }).exec(function(err, results) {
                if (err) {
                    logger.error(err);
                    return res.send(resultJson(dbHelper.dataDuplicate(err)));
                }
                if (cb) {
                    logger.debug('cb');
                    cb(results);
                } else {
                    return res.send(resultJson(0));
                }
            });
        } else {
            item.create = new Date();
            logger.debug(item);
            new table(item).save(function(err, item) {
                if (err) {
                    logger.error(err);
                    return res.send(resultJson(dbHelper.dataDuplicate(err)));
                }
                if (cb) {
                    cb(item);
                } else {
                    return res.send(resultJson(0, item));
                }
            });
        }
    },

    detail: function(table, _id, res, cb) {
        if (!_id) {
            return res.send(resultJson(3));
        }

        table.findById(_id, function(err, item) {
            if (err) {
                logger.error(err);
                return res.send(resultJson(2));
            }

            if (cb) {
                cb(item);
            } else {
                res.send(resultJson(0, item));
            }
        });
    },

    remove: function(table, _id, res) {
        if (!_id) {
            return res.send(resultJson(3));
        }

        table.remove({
            _id: _id
        }, function(err) {
            if (err) {
                logger.error(err);
                res.send(resultJson(2));
            } else {
                res.send(resultJson(0));
            }
        });
    },

    findOne: function(table, opt, sort, res, cb) {
        table.findOne(opt).sort(sort).exec(function(err, item) {
            if (err) {
                logger.error(err);
                return res.send(resultJson(2));
            }

            if (cb) {
                cb(item);
            } else {
                return res.send(resultJson(0, item));
            }
        });
    },

    listAll: function(table, opt, sort, res, cb) {
        table.find(opt).sort(sort).exec(function(err, items) {
            if (err) {
                logger.error(err);
                return res.send(resultJson(2));
            }
            if (cb) {
                cb(items);
            } else {
                return res.send(resultJson(0, items));
            }
        });
    },

    newObject: function(table, item, res, cb) {
        if (!item.create) {
            item.create = new Date();
        }
        new table(item).save(function(err, item) {
            if (err) {
                logger.error(err);
                return res.send(resultJson(2));
            }
            if (cb) {
                cb(item);
            } else {
                return res.send(resultJson(0, item));
            }
        });
    },

    findById: function(table, id, res, cb) {
        table.findById(id).exec(function(err, item) {
            if (err) {
                logger.error(err);
                return res.send(resultJson(2));
            }

            if (cb) {
                cb(item);
            } else {
                return res.send(resultJson(0, item));
            }
        });
    },

    count: function(table, opt, res, cb) {
        table.count(opt).exec(function(err, num) {
            if (err) {
                logger.error(err);
                return res.send(resultJson(2));
            }
            if (cb) {
                cb(num);
            } else {
                return res.send(resultJson(0, {
                    num: num
                }));
            }
        });
    },

    dataDuplicate: function(err) {
        if (err.code == 11000) {
            return 10;
        } else {
            return 2;
        }
    },

    removeMany: function(table, ids, res, cb) {
        if (!ids || ids.length == 0) {
            logger.debug('ids', ids);
            return res.send(resultJson(3));
        }

        table.remove({
            _id: {
                $in: ids
            }
        }, function(err) {
            if (err) {
                logger.error(err);
                res.send(resultJson(2));
            }
            if (cb) {
                cb();
            } else {
                res.send(resultJson(0));
            }
        });
    },
    update: function(table, opt, setObj, res, cb) {
        if (!opt || !setObj) {
            return res.send(resultJson(3));
        }
        logger.debug('opt', opt);
        logger.debug('setObj', setObj);
        table.update(opt, setObj, function(err, item) {
            if (err) {
                logger.error(err);
                res.send(resultJson(2));
            }
            if (cb) {
                logger.debug(11);
                cb(item);
            }
            res.send(resultJson(0));
        })
    },

    removeByItem: function(table, opt, res, cb) {
        if (!opt) {
            logger.debug('opt', opt);
            return res.send(resultJson(3));
        }
        table.remove(opt, function(err) {
            if (err) {
                logger.error(err);
                res.send(resultJson(2));
            }
            if (cb) {
                cb();
            } else {
                res.send(resultJson(0));
            }
        });
    },
};

module.exports = dbHelper;